package fun.ipconfig.service;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;


public class Handel {
    private static Instrumentation ins;
    ClassLoader loader;
    String className ;
    Long lastModified;
    boolean ingrest = false;
    Class<?> classObject;

    public static void setIns(Instrumentation ins) {
        Handel.ins = ins;
    }
    public Handel(ClassLoader loader, String className) {
        this.loader = loader;
        this.className = className;
    }
    
    public ClassLoader getLoader() {
        return loader;
    }

    public void setLoader(ClassLoader loader) {
        this.loader = loader;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public Long getLastModified() {
        return lastModified;
    }

    public void setLastModified(Long lastModified) {
        this.lastModified = lastModified;
    }

    public boolean isIngrest() {
        return ingrest;
    }

    public void setIngrest(boolean ingrest) {
        this.ingrest = ingrest;
    }

    public Class<?> getClassObject(){
        try {
            this.classObject =  Class.forName(className, false, loader);
            return this.classObject;
        } catch (Throwable e) {
            ingrest = true;
        }
        return null;
    }
    public File getFile(String className){
        try{
            Class<?> cla = getClassObject();
            if(cla == null){
                this.ingrest = true;
                return null;
            }
            String path =  cla.getResource("").getPath();
            String []classNameSplit = className.split("[.]");
            File file =  new File(path+classNameSplit[classNameSplit.length-1]+".class");
            return file.exists() ? file : null;
        }catch(Throwable e){
            ingrest = true;
        }
        ingrest = true;
        return null;
    }

    public void upFile() {
        File f = getFile(className);
        if(f != null ){
            if(this.lastModified == null ){
                this.lastModified = f.lastModified();
                System.out.println("\033[32mlisent File: " + f.getAbsolutePath()+"\033[0m");
            }else{
                if(this.lastModified < f.lastModified()){
                    this.lastModified = f.lastModified();
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    byte[] bytes = new byte[1024];
                    FileInputStream classIo = null;
                    try{
                        classIo = new FileInputStream(f);
                        int len = -1;
                        do{
                            len = classIo.read(bytes);
                            if(len != -1){
                                bos.write(bytes, 0, len);
                            }
                        }while (len != -1);
                        ins.redefineClasses(new ClassDefinition(classObject, bos.toByteArray()));
                        System.out.println("\033[32m redefineClasses: "+ className + "\033[0m");
                    } catch (Exception e) {
                        System.out.println("\031[31m redefineClasses error: "+ className + "\033[0m");
                        e.printStackTrace();
                    }finally {
                        if(classIo != null){
                            try{
                                classIo.close();
                            }catch(Exception e){}
                        }
                        try{
                            bos.close();
                        }catch(Exception e){}
                        
                    }
                    
                }
            }
        }
    }
}

